package cz.hamacekj.dotaznikklient;

import java.io.BufferedWriter;
import java.net.Socket;

/**
 * Abstrakt všech typů otázek.
 * @author Jan Hamáček
 */
public abstract class Question {
    /*public Question(){
        this.id = ++Question.count;
    }*/
    
    /**
     * Vytvoří otázku a nastaví {@link java.io.BufferedWriter writer}, do kterého
     * bude psát odpovědi na otázky.
     * @param out {@link java.io.BufferedWriter Writer}, do kterého se budou psát
     * odpovědi.
     * @param queue Po zaslání odpovědi bude na této frontě
     * zavolán {@link QuestionsQueue#runNext() runNext}, čímž se spustí další 
     * otázka ve frontě. Toto není ideální řešení signalizace. Při rozšiřování této
     * části programu by bylo vhodné toto nahradit nějakou formou Listenerů.
     */
    public Question(BufferedWriter out, QuestionsQueue queue){
        this.out = out;
        this.unfinished = queue;
        this.id = ++Question.count;
    }
    
    /**
     * Naplní základní data objektu z prvního řádku protokolu.
     * @param firstLine První řádek protokolu.
     * @throws ProtocolException Pokud firstLine neodpovídá formátu protokolu
     */
    public abstract void fromFirstLine(String firstLine) throws ProtocolException;
    
    /**
     * Přidá k otázce parametry popsané v řádku protokolu.
     * @param dataLine Řádek protokolu.
     * @throws ProtocolException Pokud dataLine neodpovídá formátu protokolu
     */
    public abstract void addParam(String dataLine) throws ProtocolException;
    
    /**
     * Zakóduje objekt do řetězce dle protokolu. (vpodstatě náhrada serializace)
     * @return Řetězec zakódovaný k odeslání.
     */
    public abstract String toText();
    
    /**
     * Zeptá se uživatele na otázku pomocí správného dialogu a odešle odpověď do writeru out.
     */
    public abstract void invokeGUIAndSendReply();
    
    /**
     * Pokud běží nějaké GUI, okamžitě ho zavře a nebude odpovídat.
     */
    public abstract void cancel();
    
    /**
     * Funkce k zjištění, jestli je tato otázka zrovna zobrazená uživateli
     * @return true pokud je zrovna zobrazená, jinak false
     */
    public abstract boolean isDisplayed();
    
    public int getId(){
        return this.id;
    }
    public void setId(int id){
        this.id = id;
    }
    
    protected QuestionsQueue unfinished;
    protected BufferedWriter out;
    protected int id;
    protected static int count = 0;
}
